home *** CD-ROM | disk | FTP | other *** search
- //==============================================================================
- // Scn35p3: AI Scenario Script for scenario 35 player 3
- //==============================================================================
- /*
- AI owner: Dave Leary
- Scenario owner: Joe Gillum
-
- Basic AI to set villagers working and do some basic maintaining and scouting
- for the HP's Norse ally in the final scenario.
-
- */
- //==============================================================================
- // Variable for main base.
- int gMainBaseID=-1;
-
- //==============================================================================
- // Set Town Location
- //==============================================================================
- void setTownLocation(void)
- {
- //Look for the "Town Location" marker.
- kbSetTownLocation(kbGetBlockPosition("2928"));
- }
-
- //==============================================================================
- // miscStartup
- //==============================================================================
- void miscStartup(void)
- {
- // Difficulty Level check.
- int difflevel=-1;
- difflevel=aiGetWorldDifficulty();
-
- //Startup message(s).
- aiEcho("");
- aiEcho("");
- aiEcho("Scn35P3 AI Start, filename='"+cFilename+"'.");
- aiEcho("Difficulty Level="+difflevel+".");
- //Spit out the map size.
- aiEcho(" Map size is ("+kbGetMapXSize()+", "+kbGetMapZSize()+").");
- //Cheat like a bastard. Once only, though.
- kbLookAtAllUnitsOnMap();
- //Calculate some areas.
- kbAreaCalculate(1200.0);
- //Set our town location.
- setTownLocation();
- //Reset random seed
- aiRandSetSeed();
-
- //Set the base location.
- gMainBaseID=kbBaseGetMainID(cMyID);
- }
-
- //==============================================================================
- //==============================================================================
- // Attack stuff.
- //==============================================================================
- //==============================================================================
- //Shared variables.
- int numberAttacks=0;
- int attackPlayerID=-1;
-
- //TODO: Decide how to rep attack group size.
- int attackMinimumGroupSize=3;
- int attackMaximumGroupSize=5;
-
- //Attack 1 vars.
- int attackPlan1ID=-1;
-
- //Attack 2 vars.
- int attackPlan2ID=-1;
-
- // Route and path vars
- int attackRoute1ID=-1;
- int attackPath1ID=-1;
- int attackRoute2ID=-1;
- int attackPath2ID=-1;
-
- // Saved plan IDs
- int maintainPlan1ID=-1;
- int maintainPlan2ID=-1;
- int maintainPlan3ID=-1;
- int maintainPlan4ID=-1;
-
- // Unit types
- int attackerUnitTypeID1=cUnitTypeVillagerNorse;
- int attackerUnitTypeID2=cUnitTypeUlfsark;
- int attackerUnitTypeID3=cUnitTypeRaidingCavalry;
- int attackerUnitTypeID4=cUnitTypeMountainGiant;
-
- // Initial gather percentages
- float totalFoodGathererPercentage = 0.6;
- float totalWoodGathererPercentage = 0.4;
- float totalGoldGathererPercentage = 0.0;
- float totalFavorGathererPercentage = 0.0;
-
-
- //==============================================================================
- // initEcon
- //
- // Set Up the initial Econonomy.
- //==============================================================================
- void initEcon()
- {
- aiEcho("Economy Init.");
-
- /* Don't need this for what we're doing here.
- // Set our update resource handler.
- aiSetUpdateResourceEventHandler("updateResourceHandler");
- */
-
- //-- Setup AI Cost weights.
- kbSetAICostWeight(cResourceFood, 1.5);
- kbSetAICostWeight(cResourceWood, 1.0);
- kbSetAICostWeight(cResourceGold, 1.5);
- kbSetAICostWeight(cResourceFavor, 10.0);
-
- //-- Dont auto gather favor
- //totalFavorGathererPercentage = 0;
-
- //-- Set initial gatherer percentages.
- aiSetResourceGathererPercentage(cResourceFood, totalFoodGathererPercentage, false, cRGPScript);
- aiSetResourceGathererPercentage(cResourceWood, totalWoodGathererPercentage, false, cRGPScript);
- aiSetResourceGathererPercentage(cResourceGold, totalGoldGathererPercentage, false, cRGPScript);
- aiSetResourceGathererPercentage(cResourceFavor, totalFavorGathererPercentage, false, cRGPScript);
- aiNormalizeResourceGathererPercentages(cRGPScript);
-
- //-- Set up the initial resource subtype break downs.
- // aiSetResourceBreakdown(cResourceFood, cAIResourceSubTypeEasy, 1, 50, 0.9, gMainBaseID);
- // aiSetResourceBreakdown(cResourceFood, cAIResourceSubTypeHunt, 1, 50, 0.1, gMainBaseID);
- aiSetResourceBreakdown(cResourceFood, cAIResourceSubTypeFarm, 1, 50, 1.0, gMainBaseID);
- aiSetResourceBreakdown(cResourceWood, cAIResourceSubTypeEasy, 1, 50, 1.0, gMainBaseID);
- aiSetResourceBreakdown(cResourceGold, cAIResourceSubTypeEasy, 1, 50, 1.0, gMainBaseID);
- aiSetResourceBreakdown(cResourceFavor, cAIResourceSubTypeEasy, 1, 50, 1.0, gMainBaseID);
-
- //-- Set up auto-gather escrows
- aiSetAutoGatherEscrowID(cRootEscrowID);
- aiSetAutoFarmEscrowID(cRootEscrowID);
-
- //Allocate all resources to the root escrow by setting percentage of military/economy to 0.
- kbEscrowSetPercentage( cEconomyEscrowID, cAllResources, 0.0 );
- kbEscrowSetPercentage( cMilitaryEscrowID, cAllResources, 0.0 );
-
- //-- create a herd plan to gather all herdables that we ecounter.
- /*
- int herdPlanID=aiPlanCreate("HerdTest", cPlanHerd);
- if (herdPlanID >= 0)
- {
- aiPlanAddUnitType(herdPlanID, cUnitTypeHerdable, 0, 100, 100);
- aiPlanSetVariableInt(herdPlanID, cHerdPlanBuildingTypeID, 0, cUnitTypeSettlementLevel1);
- aiPlanSetActive(herdPlanID);
- }
- */
-
- //Allocate all resources
- kbEscrowAllocateCurrentResources();
- }
-
- //==============================================================================
- // initAttack: Creates attack routes, etc.
- //==============================================================================
- void initAttack(int playerID=-1)
- {
- //Destroy all previous attacks (if this isn't the player we're already attacking.
- if (playerID != attackPlayerID)
- {
- //Reset the attack player ID.
- attackPlayerID=-1;
- //Destroy any previous attack plan.
- aiPlanDestroy(attackPlan1ID);
- attackPlan1ID=-1;
- aiPlanDestroy(attackPlan2ID);
- attackPlan2ID=-1;
-
- //Destroy our previous attack paths.
- kbPathDestroy(attackPath1ID);
- attackPath1ID=-1;
- kbPathDestroy(attackPath2ID);
- attackPath2ID=-1;
-
- //Destroy our previous attack routes.
- attackRoute1ID=-1;
- attackRoute2ID=-1;
-
- //Reset the number of attacks.
- numberAttacks=0;
- }
-
- //Save the player to attack.
- attackPlayerID=playerID;
-
- /*
-
- vector gatherPoint=kbGetBlockPosition("3102");
-
- //Setup attack path 1 - go left
- attackPath1ID=kbPathCreate("Attack Path 1");
- kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("3990"));
- kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("3991"));
- kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("3992"));
- //Create attack route 1.
- attackRoute1ID=kbCreateAttackRouteWithPath("Attack Route 1", gatherPoint, kbGetBlockPosition("3995"));
-
- if (attackRoute1ID >= 0)
- kbAttackRouteAddPath(attackRoute1ID, attackPath1ID);
-
- //Setup attack path 2 - go right
- attackPath2ID=kbPathCreate("Attack Path 2");
- kbPathAddWaypoint(attackPath2ID, kbGetBlockPosition("3990"));
- kbPathAddWaypoint(attackPath2ID, kbGetBlockPosition("3991"));
- kbPathAddWaypoint(attackPath2ID, kbGetBlockPosition("3993"));
- kbPathAddWaypoint(attackPath2ID, kbGetBlockPosition("3994"));
- //Create attack route 2.
- attackRoute2ID=kbCreateAttackRouteWithPath("Attack Route 2", gatherPoint, kbGetBlockPosition("3995"));
-
- if (attackRoute2ID >= 0)
- kbAttackRouteAddPath(attackRoute2ID, attackPath2ID);
- */
- }
-
- //==============================================================================
- // setupAttack
- //==============================================================================
- bool setupAttack(int playerID=-1)
- {
-
- //Info.
- aiEcho("Attacking Player "+playerID+".");
-
- //If the player to attack doesn't match, init the attack.
- if (attackPlayerID != playerID)
- {
- initAttack(playerID);
- if (attackPlayerID < 0)
- return(false);
- }
-
- //Create an attack plan.
- int newAttackPlanID=aiPlanCreate("Attack Player"+attackPlayerID+" Attempt"+numberAttacks, cPlanAttack);
- if (newAttackPlanID < 0)
- return(false);
-
- //Target player (required). This must work.
- if (aiPlanSetVariableInt(newAttackPlanID, cAttackPlanPlayerID, 0, attackPlayerID) == false)
- return(false);
-
- //Gather point.
- vector gatherPoint=kbGetBlockPosition("3127");
-
- //Set the target type. This must work.
- if (aiPlanSetNumberVariableValues(newAttackPlanID, cAttackPlanTargetTypeID, 2, true) == false)
- return(false);
-
- //Unit types to attack.
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanTargetTypeID, 0, cUnitTypeUnit);
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanTargetTypeID, 1, cUnitTypeBuilding);
-
- //Attack route.
- /*
- if (randomPath == 0)
- {
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanAttackRouteID, 0, attackRoute1ID);
- }
- else
- {
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanAttackRouteID, 0, attackRoute2ID);
- }
- */
-
- //Set the gather point and gather point distance.
- aiPlanSetVariableVector(newAttackPlanID, cAttackPlanGatherPoint, 0, gatherPoint);
- aiPlanSetVariableFloat(newAttackPlanID, cAttackPlanGatherDistance, 0, 40.0);
-
- //Set up the attack route usage pattern.
- aiPlanSetVariableInt(newAttackPlanID, cAttackPlanAttackRoutePattern, 0, cAttackPlanAttackRoutePatternRandom);
-
- //Add the unit types to the plan - cav...
- aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID3, 4, 4, 8);
- //...and ulfsarks...
- aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID2, 0, 2, 6);
- // ...and a single mountain giant, if available.
- aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID4, 0, 1, 1);
-
- //Set the initial position.
- aiPlanSetInitialPosition(newAttackPlanID, gatherPoint);
- //Plan requires all need units to work (can be false).
- aiPlanSetRequiresAllNeedUnits(newAttackPlanID, true);
- //Activate the plan.
- aiPlanSetActive(newAttackPlanID);
-
- //Now, save the attack plan ID appropriately.
- aiPlanSetOrphan(attackPlan1ID, true);
- attackPlan1ID=newAttackPlanID;
-
- //Increment our overall number of attacks.
- numberAttacks++;
- }
-
- //==============================================================================
- // createUnitProgression
- //==============================================================================
- int createUnitProgression(int unitTypeID=-1, string name="BUG")
- {
- int pID=aiPlanCreate(name, cPlanProgression);
-
- if (pID < 0)
- return(-1);
-
- //This is a military plan.
- //aiPlanSetMilitary(pID, true);
- //Set it for the building that we get our unit from.
- aiPlanSetVariableInt(pID, cProgressionPlanGoalUnitID, 0, kbTechTreeGetUnitIDByTrain(unitTypeID));
-
- //Build it in our main base using the root escrow.
- aiPlanSetBaseID(pID, gMainBaseID);
- aiPlanSetEscrowID(pID, cRootEscrowID);
-
- //Go.
- aiPlanSetActive(pID);
- return(pID);
- }
-
- //==============================================================================
- // createTechProgression
- //==============================================================================
- int createTechProgression(int techID=-1, string name="BUG", int researchFromProto=-1)
- {
- //Check for old plan.
- int oldPlanID=aiPlanGetIDByTypeAndVariableType(cPlanProgression, cProgressionPlanGoalTechID, techID);
- if(oldPlanID != -1)
- {
- aiEcho("createTechProgression: already have a plan("+oldPlanID+") for this Tech("+techID+").");
- return(oldPlanID);
- }
-
- //Create a new one.
- int pID=aiPlanCreate(name, cPlanProgression);
- if (pID < 0)
- {
- aiEcho("createTechProgression: couldn't create Progression.");
- return(-1);
- }
- //This is a military plan.
- //aiPlanSetMilitary(pID, true);
- aiPlanSetVariableInt(pID, cProgressionPlanGoalTechID, 0, techID);
- aiPlanSetVariableInt(pID, cProgressionPlanBuildingPref, 0, researchFromProto);
-
- //Build it in our main base using the root escrow.
- aiPlanSetBaseID(pID, gMainBaseID);
- aiPlanSetEscrowID(pID, cRootEscrowID);
-
- //Go.
- aiPlanSetActive(pID);
- aiEcho("createTechProgression: creating Tech Progression("+name+") to TechID("+techID+").");
- return(pID);
- }
-
- //==============================================================================
- // Attack Generator 1 - Send dudes now! Or, well, soon.
- //==============================================================================
-
- rule attackGenerator1
- minInterval 90
- inactive
- group AttackRules
- {
- //See how many "idle" attack plans we have. Don't create any more if we have
- //idle plans.
- int numberIdleAttackPlans=aiGetNumberIdlePlans(cPlanAttack);
-
- if (numberIdleAttackPlans > 0)
- return;
-
- //If we have enough unassigned military units, create a new attack plan.
- int numberAvailableUnits=aiNumberUnassignedUnits(attackerUnitTypeID3);
- aiEcho("There are "+numberAvailableUnits+" raiding cav available for a new attack.");
-
- if (numberAvailableUnits >= 4)
- setupAttack(1);
- }
-
- //==============================================================================
- // longhouseBuilt - called with an AI FUNC when he has one longhouse.
- //==============================================================================
- /*
- void longhouseBuilt( int parameter=-1 )
- {
- vector gatherPointCavalry=kbGetBlockPosition("3126");
-
- //Maintain raiding cavalry. Up to eight.
- maintainPlan3ID=aiPlanCreate("Maintain 8 "+kbGetProtoUnitName(attackerUnitTypeID3), cPlanTrain);
- if (maintainPlan3ID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainPlan3ID, cTrainPlanUnitType, 0, attackerUnitTypeID3);
- //Set the number of units to maintain in the world at one time.
- aiPlanSetVariableInt(maintainPlan3ID, cTrainPlanNumberToMaintain, 0, 8);
- //Don't train units faster than every 20 seconds
- aiPlanSetVariableInt(maintainPlan3ID, cTrainPlanFrequency, 0, 20);
- //Set a gather point.
- aiPlanSetVariableVector(maintainPlan3ID, cTrainPlanGatherPoint, 0, gatherPointCavalry);
- //Activate the plan.
- aiPlanSetActive(maintainPlan3ID);
- }
-
- // Time for lots more villagers.
- aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanNumberToMaintain, 0, 30);
-
- // Time for more ulfsarks. Maintain ten now.
- aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanNumberToMaintain, 0, 10);
-
- // Change percentage of who's on what.
- aiSetResourceGathererPercentage(cResourceFood, 0.6, false, cRGPScript);
- aiSetResourceGathererPercentage(cResourceWood, 0.1, false, cRGPScript);
- aiSetResourceGathererPercentage(cResourceGold, 0.3, false, cRGPScript);
- aiNormalizeResourceGathererPercentages(cRGPScript);
-
- // Food resource breakdown now changes to almost entirely farms.
- aiSetResourceBreakdown(cResourceFood, cAIResourceSubTypeEasy, 1, 10, 0.2, gMainBaseID);
- aiSetResourceBreakdown(cResourceFood, cAIResourceSubTypeHunt, 1, 10, 0.1, gMainBaseID);
- aiSetResourceBreakdown(cResourceFood, cAIResourceSubTypeFarm, 1, 50, 0.7, gMainBaseID);
-
- // Research some techs.
- createTechProgression(cTechHeavyInfantry, "Research Heavy Infantry", cUnitTypeLonghouse);
- createTechProgression(cTechHeavyCavalry, "Research Heavy Cavalry", cUnitTypeLonghouse);
- createTechProgression(cTechIrrigation, "Research Plow", cUnitTypeOxCart);
-
- // Progress to Huskarls - kind of a hack, used to get him to build a hill fort.
- createUnitProgression(cUnitTypeHuskarl, "Progression to Huskarls");
-
- // Activate attacks. Time to beat up on the player.
- xsEnableRule("attackGenerator1");
- }
-
- //==============================================================================
- // hillFortBuilt - called with an AI FUNC when he has one hill fort.
- //==============================================================================
- void hillFortBuilt( int parameter=-1 )
- {
- vector gatherPointGiants=kbGetBlockPosition("3125");
-
- //Maintain a single mountain giant. Adds to the fun. :)
- maintainPlan4ID=aiPlanCreate("Maintain 1 "+kbGetProtoUnitName(attackerUnitTypeID4), cPlanTrain);
- if (maintainPlan4ID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainPlan4ID, cTrainPlanUnitType, 0, attackerUnitTypeID4);
- //Set the number of units to maintain in the world at one time.
- aiPlanSetVariableInt(maintainPlan4ID, cTrainPlanNumberToMaintain, 0, 1);
- //Don't train units faster than every 60 seconds
- aiPlanSetVariableInt(maintainPlan4ID, cTrainPlanFrequency, 0, 60);
- //Set a gather point.
- aiPlanSetVariableVector(maintainPlan4ID, cTrainPlanGatherPoint, 0, gatherPointGiants);
- //Activate the plan.
- aiPlanSetActive(maintainPlan4ID);
- }
-
- // Change percentage of who's on what.
- aiSetResourceGathererPercentage(cResourceFood, 0.5, false, cRGPScript);
- aiSetResourceGathererPercentage(cResourceWood, 0.1, false, cRGPScript);
- aiSetResourceGathererPercentage(cResourceGold, 0.4, false, cRGPScript);
- }
- */
-
- //==============================================================================
- // MAIN.
- //==============================================================================
- void main(void)
- {
- //Startup.
- miscStartup();
- initEcon();
-
- //Share a common gather point.
- vector gatherPointMilitary=kbGetBlockPosition("2928");
-
- // Cheat up some favor. It's tough to be Norse.
- aiResourceCheat( 3, cResourceFavor, 45.0 );
-
- //Maintain villagers. Fifteen should do it.
- /*
- maintainPlan1ID=aiPlanCreate("Maintain 15 "+kbGetProtoUnitName(attackerUnitTypeID1), cPlanTrain);
- if (maintainPlan1ID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanUnitType, 0, attackerUnitTypeID1);
- //You can limit the number of units that are ever trained by this plan with this call.
- //aiPlanSetVariableInt(maintainPlanID, cTrainPlanNumberToTrain, 0, 25);
- //Set the number of units to maintain in the world at one time.
- aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanNumberToMaintain, 0, 12);
- //Don't train units faster than every 15 seconds
- aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanFrequency, 0, 15);
- //Set a gather point.
- aiPlanSetVariableVector(maintainPlan1ID, cTrainPlanGatherPoint, 0, gatherPointVillager);
- //Activate the plan.
- aiPlanSetActive(maintainPlan1ID);
- }
- */
-
- //Maintain ulfsarks!
- maintainPlan2ID=aiPlanCreate("Maintain 5 "+kbGetProtoUnitName(attackerUnitTypeID2), cPlanTrain);
- if (maintainPlan2ID >= 0)
- {
- //Must set the type of unit to train.
- aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanUnitType, 0, attackerUnitTypeID2);
- //You can limit the number of units that are ever trained by this plan with this call.
- //aiPlanSetVariableInt(maintainPlanID, cTrainPlanNumberToTrain, 0, 25);
- //Set the number of units to maintain in the world at one time.
- aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanNumberToMaintain, 0, 8);
- //Don't train units faster than every 45 seconds
- aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanFrequency, 0, 45);
- //Set a gather point.
- aiPlanSetVariableVector(maintainPlan2ID, cTrainPlanGatherPoint, 0, gatherPointMilitary);
- //Activate the plan.
- aiPlanSetActive(maintainPlan2ID);
- }
-
- int exploreID1 = aiPlanCreate("Explore 1", cPlanExplore);
- if(exploreID1 >= 0)
- {
- aiPlanAddUnitType(exploreID1, cUnitTypeRaven, 1, 1, 1);
- aiPlanSetActive(exploreID1);
- }
- int exploreID2 = aiPlanCreate("Explore 2", cPlanExplore);
- if(exploreID2 >= 0)
- {
- aiPlanAddUnitType(exploreID2, cUnitTypeRaven, 1, 1, 1);
- aiPlanSetVariableBool(exploreID2, cExplorePlanDoLoops, 0, false);
- aiPlanSetActive(exploreID2);
- }
- }
-